package com.bdqn;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Main {

    public static void main(String[] args) {
	// write your code here
        //类的基本信息
        Class clz = Person.class;
        String fullName = clz.getName();
        String simpleName = clz.getSimpleName();
        System.out.println("以下是"+fullName+"类的基本类型");
        System.out.println("----------------------");
        //获取Person类所在包的位置
        Package pkg = clz.getPackage();
        System.out.println(simpleName+"定义在"+pkg.getName()+"包中");
        System.out.println("----------------------");
        //获得clz所表示的实体（类、接口、基本类型或void）所继承的Class
        //如果clz表示Object、一个接口、一个基本类型或void，则返回Null
        //如果clz表示一个数组，则返回表示Object类的Class实例
        Class superClass = clz.getSuperclass();
        System.out.println(simpleName+"类所继承的类是"+superClass.getName());
        System.out.println("----------------------");
        //如果clz所表示的类实现的接口
        //如果clz表示一个不实现任何类的接口的类或接口，则此方法返回一个长度为0的数组
        //如果clz表示一个基本类型或void,则此方法返回一个长度为0的数组
        Class[] interfaces = clz.getInterfaces();
        System.out.print(simpleName+"类所实现的接口：");
        for (Class c : interfaces){
            System.out.println("\t"+c.getName());
        }
        System.out.println("----------------------");
        //每个修饰符对应一个int常量，返回的修饰符信息将类所拥有的修饰符以或运算符
        //通过与Modifier类中的常量进行与运算即可判断该类型是否拥有某个修饰符
        int modifier = clz.getModifiers();
        System.out.println(simpleName+"类的修饰符：");
        if ((modifier & Modifier.PUBLIC)==Modifier.PUBLIC){
            System.out.println("\t访问修饰符是：public");
        }else {
            System.out.println("\t访问修饰符是：default(package)");
        }
        if ((modifier & Modifier.FINAL)==Modifier.FINAL){
            System.out.println("\t访问修饰符是：final");
        }
        if ((modifier & Modifier.ABSTRACT)==Modifier.ABSTRACT){
            System.out.println("\t这是一个抽象类");
        }
        if ((modifier & Modifier.INTERFACE)==Modifier.INTERFACE){
            System.out.println("\t这是一个接口");
        }

        //构造方法基本信息
        Constructor[] cons = Person.class.getDeclaredConstructors();
        System.out.println("===============构造方法展示===========");
        for (Constructor con: cons){
            System.out.print("访问修饰符：");
            //判断该构造方法的访问修饰符
            if ((modifier & Modifier.PUBLIC)==Modifier.PUBLIC){
                System.out.println("public");
            }else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE){
                System.out.println("private");
            } else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED){
                System.out.println("protected");
            }else {
                System.out.println("default(package)");
            }
            //获取构造方法的参数列表
            Class[] params = con.getParameterTypes();
            if (params.length==0){
                System.out.println("该构造函数没有参数");
            }else {
                System.out.print("改构造函数的参数列表为：[");
                for (int i = 0; i<params.length;i++){
                    if (i!=0){
                        System.out.print(",");
                    }
                    System.out.print(params[i].getName());
                }
                System.out.println("]");
            }
            System.out.println("========================");
        }
        Field[] fields = Person.class.getDeclaredFields();
        System.out.println("========属性展示=============");
        for (Field field:fields){
            int modifier1 =field.getModifiers();
            if ((modifier1 & Modifier.PUBLIC)==Modifier.PUBLIC){
                System.out.println("public");
            }else if ((modifier1 & Modifier.PRIVATE) == Modifier.PRIVATE){
                System.out.println("private");
            } else if ((modifier1 & Modifier.PROTECTED) == Modifier.PROTECTED){
                System.out.println("protected");
            }else {
                System.out.println("default(package)");
            }
            //判断是否有static修饰符
            if ((modifier & Modifier.STATIC)==Modifier.STATIC) {
                System.out.println("这是一个静态属性");
            }
            if ((modifier & Modifier.FINAL)==Modifier.FINAL) {
                System.out.println("这是一个final属性");
            }
        }
        System.out.println("=====================================================");

        Method[] methods = Person.class.getDeclaredMethods();
        System.out.println("==================方法展示==========");
        for (Method method:methods){
            System.out.println("方法名："+method.getName());
            System.out.println("返回值类型："+method.getReturnType().getName());
            //获取方法的参数列表
            Class[] params = method.getParameterTypes();
            if (params.length==0){
                System.out.println("该构造函数没有参数");
            }else {
                System.out.print("改构造函数的参数列表为：[");
                for (int i = 0; i<params.length;i++){
                    if (i!=0){
                        System.out.print(",");
                    }
                    System.out.print(params[i].getName());
                }
                System.out.println("]");
            }
            System.out.print("访问修饰符：");
            int modifier2 = method.getModifiers();
            if ((modifier2 & Modifier.PUBLIC)==Modifier.PUBLIC){
                System.out.println("public");
            }else if ((modifier2 & Modifier.PRIVATE) == Modifier.PRIVATE){
                System.out.println("private");
            } else if ((modifier2 & Modifier.PROTECTED) == Modifier.PROTECTED){
                System.out.println("protected");
            }else {
                System.out.println("default(package)");
            }
            //判断是否有static修饰符
            if ((modifier2 & Modifier.STATIC)==Modifier.STATIC) {
                System.out.println("这是一个静态方法");
            }
            if ((modifier2 & Modifier.FINAL)==Modifier.FINAL) {
                System.out.println("这是一个final方法");
            }
            if ((modifier2 & Modifier.SYNCHRONIZED)==Modifier.SYNCHRONIZED) {
                System.out.println("这是一个同步方法");
            }
            //获取方法所属的类或接口的Class实例
            Class declaringClass = method.getDeclaringClass();
            System.out.println("方法声明在"+declaringClass.getName()+"中");
            //获取方法抛出的异常类型，即throws子句声明的异常
            Class[] exception = method.getExceptionTypes();
            if (exception.length>0){
                System.out.print("该方法抛出的异常有：[");
                for (int i = 0; i<exception.length;i++){
                    if (i!= 0){
                        System.out.print("，");
                    }
                    System.out.println(exception[i].getName());
                }
                System.out.println("]");
            }
            System.out.println("========================================");
        }
        //通过反射加载一个Parson实例

    }
}
